package LinkRetriever;


import java.io.*;
import java.util.ArrayList;
import General.*;
import java.io.ByteArrayInputStream;
import javax.xml.stream.*;
import javax.xml.stream.events.XMLEvent;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Manuel
 */

public class MapParser {

    private int elementCounter;


    public ArrayList<String> parse(String xmlData){

        elementCounter = 0;
        String xml = xmlData.toLowerCase();
        ArrayList<String> links = new ArrayList<String>();
        //If the map is from sourceforge

        if(xml.contains("sourceforge")){
            
            ArrayList<String> maps = new ArrayList();
            maps = getArrayListElements(xmlData, Globals.ELEMENTNAME);
            String allLinks = "";
            String currentData, currentLinks;

            for(int i = 0;i< maps.size();i++){
                currentData = RequestMaker.getMap(maps.get(i));
                currentLinks = getListedElements(currentData, Globals.ELEMENTNAME,"project",true);
                links.add(currentLinks);
                if(elementCounter>=Globals.crawlLimit)
                    break;
            }

            return links;

        }


        //if the map is from ....


        return links;
    }


    //returns the character content of the elements in a conitnuous string, given xml file, elementname, whether unique elements (also children should be returned) and a filter word
    public String getListedElements(String xmlData, String elementName, String mustContain, boolean unique){
      String elements = "";
      boolean nextIsElement = false;
      String root = "";
      try {
            InputStream is = new ByteArrayInputStream(xmlData.getBytes("UTF-8"));
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader r = factory.createXMLEventReader(is);
            while(r.hasNext() && elementCounter<Globals.crawlLimit) {
                XMLEvent e = r.nextEvent();
                if(e.getEventType() == XMLEvent.START_ELEMENT){
                        if(e.toString().contains(elementName))
                            nextIsElement = true;
                }

                else if(e.getEventType() == XMLEvent.CHARACTERS && nextIsElement && e.toString().contains(mustContain))
                {

                        String newLink = e.toString() + ";";

                        if(unique){
                            if(root.equals("") || !newLink.contains(root)){
                                elements = elements + newLink;
                                elementCounter++;
                                root = e.toString();
                            }
                        }

                        else{
                            elements = elements + newLink;
                            elementCounter++;
                        }
                        nextIsElement = false;
                }

            }
            is.close();

      } catch (Exception e) {
            System.err.println("Could not parse Sitemap"+e.getMessage());
      }
      return elements;

    }


    //returns all elements of a certain name, given an xml file in String format
    public ArrayList<String> getArrayListElements(String xmlData, String elementName){
      ArrayList<String> elements = new ArrayList();
      boolean nextIsElement = false;
      try {
            InputStream is = new ByteArrayInputStream(xmlData.getBytes("UTF-8"));
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLEventReader r = factory.createXMLEventReader(is);
            while(r.hasNext()) {
                XMLEvent e = r.nextEvent();
                if(e.getEventType() == XMLEvent.START_ELEMENT){
                        if(e.toString().contains(elementName)){
                            nextIsElement = true;
                        }
                }

                else if((e.getEventType() == XMLEvent.CHARACTERS) && nextIsElement)
                {
                        elements.add(e.toString());
                        nextIsElement = false;
                }
            }
            is.close();

      } catch (Exception e) {
            System.err.println("Could not parse Sitemap");
      }
      return elements;

    }
}
